home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / logic.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  9KB  |  399 lines

  1. /* $Id: logic.c,v 3.0 1998/01/31 20:58:06 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: logic.c,v $
  26.  * Revision 3.0  1998/01/31 20:58:06  brianp
  27.  * initial rev
  28.  *
  29.  */
  30.  
  31.  
  32. #ifdef PC_HEADER
  33. #include "all.h"
  34. #else
  35. #include <stdlib.h>
  36. #include "alphabuf.h"
  37. #include "context.h"
  38. #include "logic.h"
  39. #include "macros.h"
  40. #include "pb.h"
  41. #include "span.h"
  42. #include "types.h"
  43. #endif
  44.  
  45.  
  46.  
  47. void gl_LogicOp( GLcontext *ctx, GLenum opcode )
  48. {
  49.    if (INSIDE_BEGIN_END(ctx)) {
  50.       gl_error( ctx, GL_INVALID_OPERATION, "glLogicOp" );
  51.       return;
  52.    }
  53.    switch (opcode) {
  54.       case GL_CLEAR:
  55.       case GL_SET:
  56.       case GL_COPY:
  57.       case GL_COPY_INVERTED:
  58.       case GL_NOOP:
  59.       case GL_INVERT:
  60.       case GL_AND:
  61.       case GL_NAND:
  62.       case GL_OR:
  63.       case GL_NOR:
  64.       case GL_XOR:
  65.       case GL_EQUIV:
  66.       case GL_AND_REVERSE:
  67.       case GL_AND_INVERTED:
  68.       case GL_OR_REVERSE:
  69.       case GL_OR_INVERTED:
  70.          ctx->Color.LogicOp = opcode;
  71.          ctx->NewState |= NEW_RASTER_OPS;
  72.      return;
  73.       default:
  74.          gl_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
  75.      return;
  76.    }
  77. }
  78.  
  79.  
  80.  
  81. /*
  82.  * Apply logic op to array of CI pixels.
  83.  */
  84. static void index_logicop( GLcontext *ctx, GLuint n,
  85.                            GLuint index[], const GLuint dest[],
  86.                            const GLubyte mask[] )
  87. {
  88.    GLuint i;
  89.    switch (ctx->Color.LogicOp) {
  90.       case GL_CLEAR:
  91.          for (i=0;i<n;i++) {
  92.         if (mask[i]) {
  93.            index[i] = 0;
  94.         }
  95.      }
  96.      break;
  97.       case GL_SET:
  98.          for (i=0;i<n;i++) {
  99.         if (mask[i]) {
  100.            index[i] = 1;
  101.         }
  102.      }
  103.      break;
  104.       case GL_COPY:
  105.      /* do nothing */
  106.      break;
  107.       case GL_COPY_INVERTED:
  108.          for (i=0;i<n;i++) {
  109.         if (mask[i]) {
  110.            index[i] = ~index[i];
  111.         }
  112.      }
  113.      break;
  114.       case GL_NOOP:
  115.          for (i=0;i<n;i++) {
  116.         if (mask[i]) {
  117.            index[i] = dest[i];
  118.         }
  119.      }
  120.      break;
  121.       case GL_INVERT:
  122.          for (i=0;i<n;i++) {
  123.         if (mask[i]) {
  124.            index[i] = ~dest[i];
  125.         }
  126.      }
  127.      break;
  128.       case GL_AND:
  129.          for (i=0;i<n;i++) {
  130.         if (mask[i]) {
  131.            index[i] &= dest[i];
  132.         }
  133.      }
  134.      break;
  135.       case GL_NAND:
  136.          for (i=0;i<n;i++) {
  137.         if (mask[i]) {
  138.            index[i] = ~(index[i] & dest[i]);
  139.         }
  140.      }
  141.      break;
  142.       case GL_OR:
  143.          for (i=0;i<n;i++) {
  144.         if (mask[i]) {
  145.            index[i] |= dest[i];
  146.         }
  147.      }
  148.      break;
  149.       case GL_NOR:
  150.          for (i=0;i<n;i++) {
  151.         if (mask[i]) {
  152.            index[i] = ~(index[i] | dest[i]);
  153.         }
  154.      }
  155.      break;
  156.       case GL_XOR:
  157.          for (i=0;i<n;i++) {
  158.         if (mask[i]) {
  159.            index[i] ^= dest[i];
  160.         }
  161.      }
  162.      break;
  163.       case GL_EQUIV:
  164.          for (i=0;i<n;i++) {
  165.         if (mask[i]) {
  166.            index[i] = ~(index[i] ^ dest[i]);
  167.         }
  168.      }
  169.      break;
  170.       case GL_AND_REVERSE:
  171.          for (i=0;i<n;i++) {
  172.         if (mask[i]) {
  173.            index[i] = index[i] & ~dest[i];
  174.         }
  175.      }
  176.      break;
  177.       case GL_AND_INVERTED:
  178.          for (i=0;i<n;i++) {
  179.         if (mask[i]) {
  180.            index[i] = ~index[i] & dest[i];
  181.         }
  182.      }
  183.      break;
  184.       case GL_OR_REVERSE:
  185.          for (i=0;i<n;i++) {
  186.         if (mask[i]) {
  187.            index[i] = index[i] | ~dest[i];
  188.         }
  189.      }
  190.      break;
  191.       case GL_OR_INVERTED:
  192.          for (i=0;i<n;i++) {
  193.         if (mask[i]) {
  194.            index[i] = ~index[i] | dest[i];
  195.         }
  196.      }
  197.      break;
  198.       default:
  199.      gl_error( ctx, GL_INVALID_ENUM, "gl_logic error" );
  200.    }
  201. }
  202.  
  203.  
  204.  
  205. /*
  206.  * Apply the current logic operator to a span of CI pixels.  This is only
  207.  * used if the device driver can't do logic ops.
  208.  */
  209. void gl_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  210.                          GLuint index[], GLubyte mask[] )
  211. {
  212.    GLuint dest[MAX_WIDTH];
  213.    /* Read dest values from frame buffer */
  214.    (*ctx->Driver.ReadCI32Span)( ctx, n, x, y, dest );
  215.    index_logicop( ctx, n, index, dest, mask );
  216. }
  217.  
  218.  
  219.  
  220. /*
  221.  * Apply the current logic operator to an array of CI pixels.  This is only
  222.  * used if the device driver can't do logic ops.
  223.  */
  224. void gl_logicop_ci_pixels( GLcontext *ctx,
  225.                            GLuint n, const GLint x[], const GLint y[],
  226.                            GLuint index[], GLubyte mask[] )
  227. {
  228.    GLuint dest[PB_SIZE];
  229.    /* Read dest values from frame buffer */
  230.    (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
  231.    index_logicop( ctx, n, index, dest, mask );
  232. }
  233.  
  234.  
  235.  
  236. /*
  237.  * Apply logic operator to rgba pixels.
  238.  * Input:  ctx - the context
  239.  *         n - number of pixels
  240.  *         mask - pixel mask array
  241.  * In/Out:  src - incoming pixels which will be modified
  242.  * Input:  dest - frame buffer values
  243.  *
  244.  * Note:  Since the R, G, B, and A channels are all treated the same we
  245.  * process them as 4-byte GLuints instead of four GLubytes.
  246.  */
  247. static void rgba_logicop( const GLcontext *ctx, GLuint n,
  248.                           const GLubyte mask[],
  249.                           GLuint src[], const GLuint dest[] )
  250. {
  251.    GLuint i;
  252.    switch (ctx->Color.LogicOp) {
  253.       case GL_CLEAR:
  254.          for (i=0;i<n;i++) {
  255.             if (mask[i]) {
  256.                src[i] = 0;
  257.             }
  258.          }
  259.          break;
  260.       case GL_SET:
  261.          for (i=0;i<n;i++) {
  262.             if (mask[i]) {
  263.                src[i] = 0xffffffff;
  264.             }
  265.          }
  266.          break;
  267.       case GL_COPY:
  268.          /* do nothing */
  269.          break;
  270.       case GL_COPY_INVERTED:
  271.          for (i=0;i<n;i++) {
  272.             if (mask[i]) {
  273.                src[i] = ~src[i];
  274.             }
  275.          }
  276.          break;
  277.       case GL_NOOP:
  278.          for (i=0;i<n;i++) {
  279.             if (mask[i]) {
  280.                src[i] = dest[i];
  281.             }
  282.          }
  283.          break;
  284.       case GL_INVERT:
  285.          for (i=0;i<n;i++) {
  286.             if (mask[i]) {
  287.                src[i] = ~dest[i];
  288.             }
  289.          }
  290.          break;
  291.       case GL_AND:
  292.          for (i=0;i<n;i++) {
  293.             if (mask[i]) {
  294.                src[i] &= dest[i];
  295.             }
  296.          }
  297.          break;
  298.       case GL_NAND:
  299.          for (i=0;i<n;i++) {
  300.             if (mask[i]) {
  301.                src[i] = ~(src[i] & src[i]);
  302.             }
  303.          }
  304.          break;
  305.       case GL_OR:
  306.          for (i=0;i<n;i++) {
  307.             if (mask[i]) {
  308.                src[i]|= dest[i];
  309.             }
  310.          }
  311.          break;
  312.       case GL_NOR:
  313.          for (i=0;i<n;i++) {
  314.             if (mask[i]) {
  315.                src[i] = ~(src[i] | dest[i]);
  316.             }
  317.          }
  318.          break;
  319.       case GL_XOR:
  320.          for (i=0;i<n;i++) {
  321.             if (mask[i]) {
  322.                src[i] ^= dest[i];
  323.             }
  324.          }
  325.          break;
  326.       case GL_EQUIV:
  327.          for (i=0;i<n;i++) {
  328.             if (mask[i]) {
  329.                src[i] = ~(src[i] ^ dest[i]);
  330.             }
  331.          }
  332.          break;
  333.       case GL_AND_REVERSE:
  334.          for (i=0;i<n;i++) {
  335.             if (mask[i]) {
  336.                src[i] = src[i] & ~dest[i];
  337.             }
  338.          }
  339.          break;
  340.       case GL_AND_INVERTED:
  341.          for (i=0;i<n;i++) {
  342.             if (mask[i]) {
  343.                src[i] = ~src[i] & dest[i];
  344.             }
  345.          }
  346.          break;
  347.       case GL_OR_REVERSE:
  348.          for (i=0;i<n;i++) {
  349.             if (mask[i]) {
  350.                src[i] = src[i] | ~dest[i];
  351.             }
  352.          }
  353.          break;
  354.       case GL_OR_INVERTED:
  355.          for (i=0;i<n;i++) {
  356.             if (mask[i]) {
  357.                src[i] = ~src[i] | dest[i];
  358.             }
  359.          }
  360.          break;
  361.       default:
  362.          /* should never happen */
  363.          gl_problem(ctx, "Bad function in rgba_logicop");
  364.    }
  365. }
  366.  
  367.  
  368.  
  369. /*
  370.  * Apply the current logic operator to a span of RGBA pixels.
  371.  * This is only used if the device driver can't do logic ops.
  372.  */
  373. void gl_logicop_rgba_span( GLcontext *ctx,
  374.                            GLuint n, GLint x, GLint y,
  375.                            GLubyte rgba[][4], const GLubyte mask[] )
  376. {
  377.    GLubyte dest[MAX_WIDTH][4];
  378.    gl_read_rgba_span( ctx, n, x, y, dest );
  379.    rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
  380. }
  381.  
  382.  
  383.  
  384. /*
  385.  * Apply the current logic operator to an array of RGBA pixels.
  386.  * This is only used if the device driver can't do logic ops.
  387.  */
  388. void gl_logicop_rgba_pixels( GLcontext *ctx,
  389.                              GLuint n, const GLint x[], const GLint y[],
  390.                              GLubyte rgba[][4], const GLubyte mask[] )
  391. {
  392.    GLubyte dest[PB_SIZE][4];
  393.    (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
  394.    if (ctx->RasterMask & ALPHABUF_BIT) {
  395.       gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
  396.    }
  397.    rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
  398. }
  399.